package cn.bby.tools.utils;

import com.intellij.ide.util.TreeClassChooser;
import com.intellij.ide.util.TreeClassChooserFactory;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiJavaFile;
import com.intellij.psi.PsiType;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import static com.intellij.psi.CommonClassNames.JAVA_UTIL_COLLECTION;
import static com.intellij.psi.CommonClassNames.JAVA_UTIL_LIST;

/**
 * @description: ClassChooseUtil
 * @author: bby
 * @date: 2025/10/21 14:08
 * @version: 1.0
 */
public class ClassChooseUtil {

    /**
     * 选择类
     *
     * @param title         对话框标题
     * @param project       项目实例
     * @param selectedClass 当前选中的类
     * @return 选中的类
     */
    public static @Nullable PsiClass chooseClass(@NotNull String title,
                                                 @NotNull Project project,
                                                 @Nullable PsiClass selectedClass) {
        TreeClassChooserFactory factory = TreeClassChooserFactory.getInstance(project);
        com.intellij.openapi.module.Module module = ModuleManager.getInstance(project).findModuleByName("your-module");
        GlobalSearchScope scope = module != null
                ? GlobalSearchScope.moduleWithDependenciesScope(module)
                : GlobalSearchScope.allScope(project);

        TreeClassChooser chooser = factory.createInheritanceClassChooser(
                title,
                scope,
                null,
                selectedClass
        );

        chooser.showDialog();
        return chooser.getSelected();
    }

    /**
     * 查找类
     *
     * @param project       项目实例
     * @param qualifiedName 类全限定名
     * @return PsiClass对象
     */
    public static PsiClass findClass(Project project, String qualifiedName) {
        if (qualifiedName == null || qualifiedName.isEmpty()) {
            return null;
        }
        GlobalSearchScope allScope = GlobalSearchScope.allScope(project);
        JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
        PsiClass[] possibleClasses = facade.findClasses(qualifiedName, allScope);
        if (possibleClasses.length == 0) {
            return null;
        }
        return possibleClasses[0];
    }

    /**
     * 检测当前焦点所在的类
     */
    public static PsiClass detectCurrentClass(Project project, Editor editor) {
        if (editor != null && project != null) {
            PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
            if (psiFile instanceof PsiJavaFile) {
                PsiClass[] classes = ((PsiJavaFile) psiFile).getClasses();
                if (classes.length > 0) {
                    // 如果光标在某个类内部，选择该类
                    int offset = editor.getCaretModel().getOffset();
                    for (PsiClass clazz : classes) {
                        if (clazz.getTextRange().getStartOffset() <= offset &&
                                clazz.getTextRange().getEndOffset() >= offset) {
                            return clazz;
                        }
                    }
                    // 否则选择第一个类
                    return classes[0];
                }
            }
        }
        return null;
    }

    /**
     * 获取PsiType
     *
     * @param project       项目实例
     * @param qualifiedName 类全限定名
     * @return PsiType对象
     */
    public static PsiType getPsiType(Project project, String qualifiedName) {
        return PsiType.getTypeByName(qualifiedName, project, GlobalSearchScope.allScope(project));
    }

    /**
     * 获取集合泛型类
     */
    public static PsiClass findCollClass(Project project, PsiType fieldType) {
        String canonicalText = fieldType.getCanonicalText();
        int start = canonicalText.indexOf('<');
        int end = canonicalText.indexOf('>');
        if (start != -1 && end != -1 && end > start) {
            return ClassChooseUtil.findClass(project, canonicalText.substring(start + 1, end));
        }
        return null;
    }

    /**
     * 判断是否是集合类型
     */
    public static boolean isCollType(Project project, PsiType type) {
        PsiType collType = ClassChooseUtil.getPsiType(project, JAVA_UTIL_COLLECTION);
        return collType.isAssignableFrom(type);
    }
}